package com.gxa.hualian.interceptor;

import com.gxa.hualian.anno.NeedToken;
import com.gxa.hualian.exception.BusinessException;
import com.gxa.hualian.exception.ExceptionCode;
import com.gxa.hualian.utils.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;

/**
 * 设计一个拦胾器,用于校验丽端是否携带token,
 * 并对token合法性进行判断*beanName: tokenInterceptor
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {
    /**
     * 拦截前的处理
     * @param httpServletRequest request对象(header/session)
     * @param httpServletResponse response响应对象(转发,通过全局异常处理就已经可以实现前端异常响应)
     * @param o 封装了一个方法的Method对象 :/user/login->login()->反射得到方法的信息->注解
     *          例如:设定一个自定义注解 @NeedToken
     * @return true 表示放行,反之表示拦死
     * @throws Exception 把所有异常都整合为一个,因为在ExceptionController的存在,会被集中处理
     */
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
       if(!(o instanceof HandlerMethod)){
           return true;
       }
        HandlerMethod handlerMethod=(HandlerMethod) o;
        Method method = handlerMethod.getMethod();
        method.getDeclaredAnnotation(NeedToken.class);
       //判断该方法上有没有需要的注解
        boolean annotationPresent = method.isAnnotationPresent(NeedToken.class);
        //
      if(annotationPresent){
          //方法存在@Needtoken,就需要验证token
          //通过header
          String token = httpServletRequest.getHeader("token");

          //服务器中存在session存的token:
          HttpSession session = httpServletRequest.getSession();
          Object sysToken = session.getAttribute("token");
          if(StringUtils.isEmpty(token)){
              throw new BusinessException(ExceptionCode.ENPTY_TOKEN);
          }else if(!token.equals(sysToken)){
              throw new BusinessException(ExceptionCode.WRONG_TOKEN);
          }
          //效验通过放行:
            return true;
      } else{
          //直接放行:
          return true;
      }
      //  return false;
    }

    /**
     * 拦截后的处理
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    /**
     * 拦截之后放行的操作
     * @param httpServletRequest
     * @param httpServletResponse
     * @param o
     * @param e
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
